package com.ccz.demo.util;

import com.ccz.demo.validation.FieldValidate;
import org.apache.commons.lang3.StringUtils;


import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ValidateUtil {

    public static String doValidate(Object obj) throws Exception {
        StringBuffer sb = new StringBuffer();
        if (obj == null) {
            return null;
        }
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            FieldValidate annotation = field.getAnnotation(FieldValidate.class);
            if (annotation != null) {
                Type type = field.getType();
                Object value = field.get(obj); // 获取对象属性值
                if (value == null) {
                    // 属性没值
                    if (annotation.isRequire()) {
                        // 必有值
                        sb.append(field.getName() + "不能为空");
//                        throw new Exception(field.getName() + "不能为空");
                    }
                    // 在某些属性不为空的情况下，属性值不能为空
                    String notNullWithOtherField = annotation.notNullWithOtherField();
                    if (StringUtils.isNotBlank(notNullWithOtherField)) {
                        boolean otherFieldHasValue = getFieldValue(obj, notNullWithOtherField);
                        if (otherFieldHasValue) {
                            sb.append(field.getName() + "在[" + notNullWithOtherField + "]值不为空时，不能为空");
//                        throw new Exception(field.getName() + "在[" + notNullWithOtherField + "]值不为空时，不能为空");
                        }
                    }
                    // 默认值设置
                    String defaultValue = annotation.defaultValue();
                    if (StringUtils.isNotEmpty(defaultValue)) {
                        field.set(obj, changeValue(field, defaultValue));
                    }
                } else {
                    // 属性有值
                    String regular = annotation.regular();
                    // 正则验证
                    if (StringUtils.isNotEmpty(regular)) {
                        Pattern pattern = Pattern.compile(regular);
                        Matcher matcher = pattern.matcher(getStringValue(field, value));
                        if (!matcher.matches()) {
                            sb.append(field.getName() + "不符合" + regular + "规则");
//                            throw new Exception(field.getName() + "不能为空");
                        }
                    }
                }
            }
        }
        return sb.toString();
    }

    /**
     * 根据属性名称获取属性值
     *
     * @param obj
     * @param fieldName
     * @return
     */
    private static boolean getFieldValue(Object obj, String fieldName) {
        Field field = null;
        if (StringUtils.isEmpty(fieldName)) {
            return true;
        }
        for (String str : fieldName.split(",")) {
            try {
                field = obj.getClass().getDeclaredField(str);
                field.setAccessible(true);
                Object value = field.get(obj);
                if (value == null) {
                    return true;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * String 值转为基本数据类型
     *
     * @param field
     * @param fieldValue
     * @return
     */
    private static Object changeValue(Field field, String fieldValue) {
        Type type = field.getType();
        String className = ((Class) type).getName().substring(((Class) type).getName().indexOf('.') == -1 ? 0 : ((Class) type).getName().lastIndexOf('.') + 1);
        if ("Integer".equals(className) || "int".equals(className)) {
            return Integer.valueOf(fieldValue);
        } else if ("Double".equals(className) || "double".equals(className)) {
            return Double.valueOf(fieldValue);
        } else if ("Short".equals(className) || "short".equals(className)) {
            return Short.valueOf(fieldValue);
        } else if ("Boolean".equals(className) || "boolean".equals(className)) {
            if ("true".equals(fieldValue)) {
                return true;
            } else {
                return false;
            }
        } else if ("Date".equals(className)) {
            try {
                return new SimpleDateFormat("yyyyMMddhhmmss").parse(fieldValue);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else if ("String".equals(className)) {
            return (String) fieldValue;
        } else {
            try {
                throw new Exception("值域出错");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 基本数据类型转为String
     *
     * @param field
     * @param fieldValue
     * @return
     */
    private static String getStringValue(Field field, Object fieldValue) {
        Type type = field.getType();
        String classNmae = ((Class) type).getName().substring(((Class) type).getName().indexOf('.') == -1 ? 0 : ((Class) type).getName().lastIndexOf('.') + 1);
        if ("Integer".equals(classNmae) || "int".equals(classNmae)) {
            return String.valueOf((Integer) fieldValue);
        } else if ("Double".equals(classNmae) || "double".equals(classNmae)) {
            return String.valueOf((Double) fieldValue);
        } else if ("Short".equals(classNmae) || "short".equals(classNmae)) {
            return String.valueOf((Short) fieldValue);
        } else if ("Boolean".equals(classNmae) || "boolean".equals(classNmae)) {
            if ((boolean) fieldValue) {
                return "1";
            } else {
                return "0";
            }
        } else if ("Date".equals(classNmae)) {
            return new SimpleDateFormat("yyyyMMddhhmmss").format((Date) fieldValue);
        } else if ("String".equals(classNmae)) {
            return (String) fieldValue;
        } else {
            try {
                throw new Exception("值域出错");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
